package aisino

import (
	"fmt"

	"gitee.com/xntk2381/invoice"
	"github.com/go-ole/go-ole"
	"github.com/go-ole/go-ole/oleutil"
)

// 冲票
func (a *AisinoInvoice) ChongPiao(req *invoice.Invoice) (resp *invoice.Info, err error) {
	var (
		retCode int16
		retMsg  string
	)
	ole.CoInitialize(0)
	unknown, err := oleutil.CreateObject("TaxCardX.GoldTax") // 创建对象
	if err != nil {
		return
	}
	defer func() {
		ole.CoUninitialize()
	}()
	tax, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return
	}
	defer func() {
		tax.Release()
	}()
	if a.Password != "" {
		_, err = tax.PutProperty("CertPassWord", a.Password)
		if err != nil {
			return
		}
	}

	_, err = tax.CallMethod("OpenCard")
	if err != nil {
		return
	}

	retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
	retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
	if retCode != 1011 {
		err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
		return
	}

	// 初始化发票整体信息各项属性
	_, err = tax.CallMethod("InvInfoInit")
	if err != nil {
		return
	}
	retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
	retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
	if retCode != 9000 {
		tax.CallMethod("CloseCard")
		err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
		return
	}

	// 设置发票类别
	tax.PutProperty("InfoKind", req.Kind)

	// 读取发票库存
	_, err = tax.CallMethod("GetInfo")
	if err != nil {
		return
	}
	retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
	retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
	if retCode != 3011 {
		tax.CallMethod("CloseCard")
		err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
		return
	}

	// 设置票面信息
	tax.PutProperty("InfoSellerBankAccount", req.SellerBankAccount)
	tax.PutProperty("InfoSellerAddressPhone", req.SellerAddressPhone)
	tax.PutProperty("InfoClientTaxCode", req.ClientTaxCode)
	tax.PutProperty("InfoClientName", req.ClientName)
	tax.PutProperty("InfoClientAddressPhone", req.ClientAddressPhone)
	tax.PutProperty("InfoInvoicer", req.Invoicer)
	tax.PutProperty("InfoChecker", req.Checker)
	tax.PutProperty("InfoCashier", req.Cashier)
	tax.PutProperty("InfoNotes", req.Notes) // 格式固定为：对应正数发票代码: + 发票代码 + 号码: + 发票号码

	// 清除明细表全部行
	_, err = tax.CallMethod("ClearInvList")
	if err != nil {
		return
	}
	retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
	retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
	if retCode != 9000 {
		tax.CallMethod("CloseCard")
		err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
		return
	}

	for _, item := range req.Items {
		// 初始化明细行
		_, err = tax.CallMethod("InvListInit")
		if err != nil {
			return
		}
		retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
		retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
		if retCode != 9000 {
			tax.CallMethod("CloseCard")
			err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
			return
		}

		tax.PutProperty("ListTaxItem", item.TaxItem)
		tax.PutProperty("ListStandard", item.Standard)
		tax.PutProperty("ListAmount", item.Amount) // 为负
		tax.PutProperty("ListNumber", item.Number) // 不能为负
		tax.PutProperty("ListPrice", item.Price)   // 为负
		tax.PutProperty("InfoTaxRate", item.TaxRate)
		tax.PutProperty("ListPriceKind", item.PriceKind)
		tax.PutProperty("ListUnit", item.Unit)
		tax.PutProperty("ListGoodsName", item.GoodsName)

		var bustr string
		bustr, err = ConvertBatchUpload(item)
		if err != nil {
			return
		}
		fmt.Printf("准备调用：%v\n", "BatchUpload")
		_, err = tax.CallMethod("BatchUpload", bustr)
		if err != nil {
			return
		}
		retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
		retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
		fmt.Printf("%v 返回 RetCode=%v RetMsg=%v\n", "BatchUpload", retCode, retMsg)

		// 将上述信息加入到明细列表
		_, err = tax.CallMethod("AddInvList")
		if err != nil {
			return
		}
		retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
		retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
		if retCode != 9000 {
			tax.CallMethod("CloseCard")
			err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
			return
		}
	}

	tax.PutProperty("CheckEWM", int16(0))
	// 发票开具
	_, err = tax.CallMethod("Invoice")
	if err != nil {
		return
	}
	retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
	retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
	if retCode != 4011 {
		tax.CallMethod("CloseCard")
		err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
		return
	}

	resp = &invoice.Info{
		Number:   oleutil.MustGetProperty(tax, "InfoNumber").Value().(string),   // 发票号
		TypeCode: oleutil.MustGetProperty(tax, "InfoTypeCode").Value().(string), // 发票代码
	}

	// 打印发票
	_, err = tax.CallMethod("PrintInv")
	if err != nil {
		return
	}
	retCode = oleutil.MustGetProperty(tax, "RetCode").Value().(int16)
	retMsg = oleutil.MustGetProperty(tax, "RetMsg").Value().(string)
	if retCode != 5011 {
		tax.CallMethod("CloseCard")
		err = fmt.Errorf("RetCode=%v RetMsg=%v", retCode, retMsg)
		return
	}
	tax.CallMethod("CloseCard")
	return
}
